#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""实用工具辅助函数"""

import os
import sys
import logging
import json
import yaml
import configparser
import time
import datetime
import hashlib
import base64
import re
import platform
import subprocess
from typing import Dict, List, Optional, Tuple, Any, Union, Callable


class HelperFunctions:
    """实用工具辅助函数类"""
    
    @staticmethod
    def setup_logger(name: str, level: int = logging.INFO, log_file: Optional[str] = None) -> logging.Logger:
        """设置日志记录器
        
        Args:
            name: 日志记录器名称
            level: 日志级别
            log_file: 日志文件路径
            
        Returns:
            logging.Logger: 配置好的日志记录器
        """
        # 创建日志记录器
        logger = logging.getLogger(name)
        logger.setLevel(level)
        
        # 避免重复添加处理器
        if not logger.handlers:
            # 创建控制台处理器
            console_handler = logging.StreamHandler()
            console_handler.setLevel(level)
            
            # 创建文件处理器（如果指定了日志文件）
            handlers = [console_handler]
            if log_file:
                # 确保日志目录存在
                log_dir = os.path.dirname(log_file)
                if log_dir and not os.path.exists(log_dir):
                    os.makedirs(log_dir, exist_ok=True)
                
                file_handler = logging.FileHandler(log_file, encoding="utf-8")
                file_handler.setLevel(level)
                handlers.append(file_handler)
            
            # 设置日志格式
            formatter = logging.Formatter(
                '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
            )
            
            # 为处理器设置格式
            for handler in handlers:
                handler.setFormatter(formatter)
                logger.addHandler(handler)
        
        return logger
    
    @staticmethod
    def load_json_file(file_path: str) -> Dict[str, Any]:
        """加载JSON文件
        
        Args:
            file_path: JSON文件路径
            
        Returns:
            Dict[str, Any]: JSON数据
            
        Raises:
            FileNotFoundError: 文件不存在
            json.JSONDecodeError: JSON解析错误
        """
        if not os.path.exists(file_path):
            raise FileNotFoundError(f"JSON文件不存在: {file_path}")
        
        with open(file_path, "r", encoding="utf-8") as f:
            return json.load(f)
    
    @staticmethod
    def save_json_file(data: Any, file_path: str, indent: int = 2) -> None:
        """保存JSON文件
        
        Args:
            data: 要保存的数据
            file_path: JSON文件路径
            indent: 缩进空格数
        """
        # 确保目录存在
        os.makedirs(os.path.dirname(file_path), exist_ok=True)
        
        with open(file_path, "w", encoding="utf-8") as f:
            json.dump(data, f, ensure_ascii=False, indent=indent)
    
    @staticmethod
    def load_yaml_file(file_path: str) -> Dict[str, Any]:
        """加载YAML文件
        
        Args:
            file_path: YAML文件路径
            
        Returns:
            Dict[str, Any]: YAML数据
            
        Raises:
            FileNotFoundError: 文件不存在
            yaml.YAMLError: YAML解析错误
        """
        if not os.path.exists(file_path):
            raise FileNotFoundError(f"YAML文件不存在: {file_path}")
        
        with open(file_path, "r", encoding="utf-8") as f:
            return yaml.safe_load(f)
    
    @staticmethod
    def save_yaml_file(data: Any, file_path: str) -> None:
        """保存YAML文件
        
        Args:
            data: 要保存的数据
            file_path: YAML文件路径
        """
        # 确保目录存在
        os.makedirs(os.path.dirname(file_path), exist_ok=True)
        
        with open(file_path, "w", encoding="utf-8") as f:
            yaml.dump(data, f, allow_unicode=True, default_flow_style=False)
    
    @staticmethod
    def load_config_file(file_path: str) -> configparser.ConfigParser:
        """加载INI配置文件
        
        Args:
            file_path: INI文件路径
            
        Returns:
            configparser.ConfigParser: 配置对象
            
        Raises:
            FileNotFoundError: 文件不存在
        """
        if not os.path.exists(file_path):
            raise FileNotFoundError(f"配置文件不存在: {file_path}")
        
        config = configparser.ConfigParser()
        config.read(file_path, encoding="utf-8")
        
        return config
    
    @staticmethod
    def save_config_file(config: configparser.ConfigParser, file_path: str) -> None:
        """保存INI配置文件
        
        Args:
            config: 配置对象
            file_path: INI文件路径
        """
        # 确保目录存在
        os.makedirs(os.path.dirname(file_path), exist_ok=True)
        
        with open(file_path, "w", encoding="utf-8") as f:
            config.write(f)
    
    @staticmethod
    def read_file(file_path: str, encoding: str = "utf-8") -> str:
        """读取文件内容
        
        Args:
            file_path: 文件路径
            encoding: 文件编码
            
        Returns:
            str: 文件内容
            
        Raises:
            FileNotFoundError: 文件不存在
        """
        if not os.path.exists(file_path):
            raise FileNotFoundError(f"文件不存在: {file_path}")
        
        with open(file_path, "r", encoding=encoding) as f:
            return f.read()
    
    @staticmethod
    def write_file(content: str, file_path: str, encoding: str = "utf-8") -> None:
        """写入文件内容
        
        Args:
            content: 要写入的内容
            file_path: 文件路径
            encoding: 文件编码
        """
        # 确保目录存在
        os.makedirs(os.path.dirname(file_path), exist_ok=True)
        
        with open(file_path, "w", encoding=encoding) as f:
            f.write(content)
    
    @staticmethod
    def append_file(content: str, file_path: str, encoding: str = "utf-8") -> None:
        """追加内容到文件
        
        Args:
            content: 要追加的内容
            file_path: 文件路径
            encoding: 文件编码
        """
        # 确保目录存在
        os.makedirs(os.path.dirname(file_path), exist_ok=True)
        
        with open(file_path, "a", encoding=encoding) as f:
            f.write(content)
    
    @staticmethod
    def get_file_extension(file_path: str) -> str:
        """获取文件扩展名
        
        Args:
            file_path: 文件路径
            
        Returns:
            str: 文件扩展名（小写）
        """
        _, ext = os.path.splitext(file_path)
        return ext.lower()
    
    @staticmethod
    def get_file_name(file_path: str, with_extension: bool = True) -> str:
        """获取文件名
        
        Args:
            file_path: 文件路径
            with_extension: 是否包含扩展名
            
        Returns:
            str: 文件名
        """
        if with_extension:
            return os.path.basename(file_path)
        else:
            name, _ = os.path.splitext(os.path.basename(file_path))
            return name
    
    @staticmethod
    def get_directory_path(file_path: str) -> str:
        """获取目录路径
        
        Args:
            file_path: 文件路径
            
        Returns:
            str: 目录路径
        """
        return os.path.dirname(file_path)
    
    @staticmethod
    def ensure_directory_exists(directory_path: str) -> None:
        """确保目录存在
        
        Args:
            directory_path: 目录路径
        """
        if not os.path.exists(directory_path):
            os.makedirs(directory_path, exist_ok=True)
    
    @staticmethod
    def list_files(directory: str, pattern: Optional[str] = None) -> List[str]:
        """列出目录中的文件
        
        Args:
            directory: 目录路径
            pattern: 文件名模式（正则表达式）
            
        Returns:
            List[str]: 文件路径列表
        """
        files = []
        
        if not os.path.exists(directory):
            return files
        
        for root, _, file_names in os.walk(directory):
            for file_name in file_names:
                file_path = os.path.join(root, file_name)
                
                # 检查文件名模式
                if pattern:
                    if re.match(pattern, file_name):
                        files.append(file_path)
                else:
                    files.append(file_path)
        
        return files
    
    @staticmethod
    def search_files(directory: str, search_text: str) -> List[str]:
        """搜索文件内容
        
        Args:
            directory: 目录路径
            search_text: 搜索文本
            
        Returns:
            List[str]: 包含搜索文本的文件路径列表
        """
        matching_files = []
        
        if not os.path.exists(directory):
            return matching_files
        
        # 遍历目录中的所有文件
        for root, _, file_names in os.walk(directory):
            for file_name in file_names:
                file_path = os.path.join(root, file_name)
                
                # 尝试读取文件内容
                try:
                    with open(file_path, "r", encoding="utf-8") as f:
                        content = f.read()
                        
                        # 检查文件是否包含搜索文本
                        if search_text in content:
                            matching_files.append(file_path)
                except Exception:
                    # 忽略无法读取的文件
                    continue
        
        return matching_files
    
    @staticmethod
    def calculate_file_hash(file_path: str, algorithm: str = "md5") -> str:
        """计算文件哈希值
        
        Args:
            file_path: 文件路径
            algorithm: 哈希算法（md5, sha1, sha256）
            
        Returns:
            str: 文件哈希值
            
        Raises:
            FileNotFoundError: 文件不存在
            ValueError: 不支持的哈希算法
        """
        if not os.path.exists(file_path):
            raise FileNotFoundError(f"文件不存在: {file_path}")
        
        # 检查哈希算法是否支持
        if algorithm not in hashlib.algorithms_available:
            raise ValueError(f"不支持的哈希算法: {algorithm}")
        
        # 创建哈希对象
        hash_obj = hashlib.new(algorithm)
        
        # 分块读取文件并计算哈希值
        block_size = 8192
        with open(file_path, "rb") as f:
            while True:
                data = f.read(block_size)
                if not data:
                    break
                hash_obj.update(data)
        
        return hash_obj.hexdigest()
    
    @staticmethod
    def encode_base64(data: Union[str, bytes]) -> str:
        """Base64编码
        
        Args:
            data: 要编码的数据
            
        Returns:
            str: Base64编码后的字符串
        """
        if isinstance(data, str):
            data = data.encode("utf-8")
        
        return base64.b64encode(data).decode("utf-8")
    
    @staticmethod
    def decode_base64(encoded_data: str) -> bytes:
        """Base64解码
        
        Args:
            encoded_data: Base64编码的字符串
            
        Returns:
            bytes: 解码后的数据
        """
        return base64.b64decode(encoded_data)
    
    @staticmethod
    def format_size(size_bytes: int) -> str:
        """格式化文件大小
        
        Args:
            size_bytes: 字节大小
            
        Returns:
            str: 格式化后的大小字符串
        """
        # 定义单位
        units = ["B", "KB", "MB", "GB", "TB", "PB"]
        
        # 计算大小
        size = float(size_bytes)
        unit_index = 0
        
        while size >= 1024 and unit_index < len(units) - 1:
            size /= 1024
            unit_index += 1
        
        # 格式化输出
        if unit_index == 0:
            return f"{int(size)} {units[unit_index]}"
        else:
            return f"{size:.2f} {units[unit_index]}"
    
    @staticmethod
    def get_file_size(file_path: str) -> int:
        """获取文件大小
        
        Args:
            file_path: 文件路径
            
        Returns:
            int: 文件大小（字节）
            
        Raises:
            FileNotFoundError: 文件不存在
        """
        if not os.path.exists(file_path):
            raise FileNotFoundError(f"文件不存在: {file_path}")
        
        return os.path.getsize(file_path)
    
    @staticmethod
    def get_file_creation_time(file_path: str) -> float:
        """获取文件创建时间
        
        Args:
            file_path: 文件路径
            
        Returns:
            float: 时间戳
            
        Raises:
            FileNotFoundError: 文件不存在
        """
        if not os.path.exists(file_path):
            raise FileNotFoundError(f"文件不存在: {file_path}")
        
        # 根据操作系统选择获取创建时间的方法
        if platform.system() == "Windows":
            return os.path.getctime(file_path)
        else:
            # macOS 和 Linux
            stat_result = os.stat(file_path)
            # 在 macOS 上使用 st_birthtime
            try:
                return stat_result.st_birthtime
            except AttributeError:
                # 在 Linux 上使用 st_ctime（表示状态更改时间）
                return stat_result.st_ctime
    
    @staticmethod
    def get_file_modification_time(file_path: str) -> float:
        """获取文件修改时间
        
        Args:
            file_path: 文件路径
            
        Returns:
            float: 时间戳
            
        Raises:
            FileNotFoundError: 文件不存在
        """
        if not os.path.exists(file_path):
            raise FileNotFoundError(f"文件不存在: {file_path}")
        
        return os.path.getmtime(file_path)
    
    @staticmethod
    def format_timestamp(timestamp: float, format_str: str = "%Y-%m-%d %H:%M:%S") -> str:
        """格式化时间戳
        
        Args:
            timestamp: 时间戳
            format_str: 时间格式字符串
            
        Returns:
            str: 格式化后的时间字符串
        """
        return datetime.datetime.fromtimestamp(timestamp).strftime(format_str)
    
    @staticmethod
    def get_current_timestamp() -> float:
        """获取当前时间戳
        
        Returns:
            float: 当前时间戳
        """
        return time.time()
    
    @staticmethod
    def get_current_datetime(format_str: str = "%Y-%m-%d %H:%M:%S") -> str:
        """获取当前日期时间
        
        Args:
            format_str: 时间格式字符串
            
        Returns:
            str: 当前日期时间字符串
        """
        return datetime.datetime.now().strftime(format_str)
    
    @staticmethod
    def execute_command(command: str, cwd: Optional[str] = None, timeout: Optional[int] = None) -> Tuple[int, str, str]:
        """执行命令行命令
        
        Args:
            command: 要执行的命令
            cwd: 工作目录
            timeout: 超时时间（秒）
            
        Returns:
            Tuple[int, str, str]: (退出码, 标准输出, 标准错误)
        """
        try:
            # 执行命令
            process = subprocess.Popen(
                command,
                shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                cwd=cwd,
                text=True
            )
            
            # 等待命令完成并获取输出
            stdout, stderr = process.communicate(timeout=timeout)
            
            # 返回退出码和输出
            return process.returncode, stdout.strip(), stderr.strip()
        except subprocess.TimeoutExpired:
            # 超时处理
            process.kill()
            return -1, "", f"命令执行超时: {timeout}秒"
        except Exception as e:
            # 其他错误处理
            return -1, "", f"命令执行失败: {str(e)}"
    
    @staticmethod
    def is_valid_path(path: str) -> bool:
        """检查路径是否有效
        
        Args:
            path: 要检查的路径
            
        Returns:
            bool: 路径是否有效
        """
        try:
            # 尝试规范化路径
            norm_path = os.path.normpath(path)
            
            # 检查路径字符是否合法
            # Windows 特殊检查
            if platform.system() == "Windows":
                # 检查是否包含非法字符
                invalid_chars = "<>|:\"?*"
                for char in invalid_chars:
                    if char in norm_path:
                        return False
                
                # 检查路径长度（Windows 有路径长度限制）
                if len(norm_path) > 260:
                    return False
            
            return True
        except Exception:
            return False
    
    @staticmethod
    def is_relative_path(path: str) -> bool:
        """检查是否是相对路径
        
        Args:
            path: 要检查的路径
            
        Returns:
            bool: 是否是相对路径
        """
        return not os.path.isabs(path)
    
    @staticmethod
    def make_absolute_path(path: str, base_path: str = None) -> str:
        """将相对路径转换为绝对路径
        
        Args:
            path: 相对路径
            base_path: 基础路径（默认为当前工作目录）
            
        Returns:
            str: 绝对路径
        """
        # 如果已经是绝对路径，直接返回
        if os.path.isabs(path):
            return os.path.normpath(path)
        
        # 确定基础路径
        if base_path is None:
            base_path = os.getcwd()
        
        # 合并路径
        return os.path.normpath(os.path.join(base_path, path))
    
    @staticmethod
    def make_relative_path(path: str, base_path: str = None) -> str:
        """将绝对路径转换为相对路径
        
        Args:
            path: 绝对路径
            base_path: 基础路径（默认为当前工作目录）
            
        Returns:
            str: 相对路径
        """
        # 确定基础路径
        if base_path is None:
            base_path = os.getcwd()
        
        # 确保路径是绝对路径
        if not os.path.isabs(path):
            path = os.path.abspath(path)
        
        if not os.path.isabs(base_path):
            base_path = os.path.abspath(base_path)
        
        # 获取相对路径
        return os.path.relpath(path, base_path)
    
    @staticmethod
    def sanitize_filename(filename: str, replacement: str = "_") -> str:
        """清理文件名中的非法字符
        
        Args:
            filename: 原始文件名
            replacement: 替换字符
            
        Returns:
            str: 清理后的文件名
        """
        # 定义非法字符
        invalid_chars = '<>"/\\|?*: 	\n\r\v\f'
        
        # 替换非法字符
        for char in invalid_chars:
            filename = filename.replace(char, replacement)
        
        # 移除多余的替换字符
        while replacement * 2 in filename:
            filename = filename.replace(replacement * 2, replacement)
        
        # 移除开头和结尾的替换字符
        filename = filename.strip(replacement)
        
        # 确保文件名不为空
        if not filename:
            filename = f"unnamed{replacement}{int(time.time())}"
        
        return filename
    
    @staticmethod
    def split_list_into_chunks(items: List[Any], chunk_size: int) -> List[List[Any]]:
        """将列表分割成多个小块
        
        Args:
            items: 原始列表
            chunk_size: 每个小块的大小
            
        Returns:
            List[List[Any]]: 分割后的列表
        """
        return [items[i:i + chunk_size] for i in range(0, len(items), chunk_size)]
    
    @staticmethod
    def merge_dicts(*dicts: Dict[Any, Any]) -> Dict[Any, Any]:
        """合并多个字典
        
        Args:
            *dicts: 要合并的字典
            
        Returns:
            Dict[Any, Any]: 合并后的字典
        """
        result = {}
        
        for d in dicts:
            result.update(d)
        
        return result
    
    @staticmethod
    def deep_merge_dicts(dict1: Dict[Any, Any], dict2: Dict[Any, Any]) -> Dict[Any, Any]:
        """深度合并两个字典
        
        Args:
            dict1: 第一个字典
            dict2: 第二个字典
            
        Returns:
            Dict[Any, Any]: 合并后的字典
        """
        result = dict1.copy()
        
        for key, value in dict2.items():
            if key in result and isinstance(result[key], dict) and isinstance(value, dict):
                # 递归合并嵌套字典
                result[key] = HelperFunctions.deep_merge_dicts(result[key], value)
            else:
                # 直接覆盖
                result[key] = value
        
        return result
    
    @staticmethod
    def flatten_dict(d: Dict[Any, Any], parent_key: str = "", sep: str = ".") -> Dict[str, Any]:
        """扁平化字典
        
        Args:
            d: 嵌套字典
            parent_key: 父键
            sep: 分隔符
            
        Returns:
            Dict[str, Any]: 扁平化后的字典
        """
        items = []
        
        for k, v in d.items():
            new_key = f"{parent_key}{sep}{k}" if parent_key else k
            
            if isinstance(v, dict):
                items.extend(HelperFunctions.flatten_dict(v, new_key, sep=sep).items())
            else:
                items.append((new_key, v))
        
        return dict(items)
    
    @staticmethod
    def unflatten_dict(d: Dict[str, Any], sep: str = ".") -> Dict[Any, Any]:
        """将扁平化的字典还原为嵌套字典
        
        Args:
            d: 扁平化的字典
            sep: 分隔符
            
        Returns:
            Dict[Any, Any]: 嵌套字典
        """
        result = {}
        
        for key, value in d.items():
            parts = key.split(sep)
            d = result
            
            for i, part in enumerate(parts):
                if i == len(parts) - 1:
                    d[part] = value
                else:
                    if part not in d:
                        d[part] = {}
                    d = d[part]
        
        return result
    
    @staticmethod
    def deduplicate_list(items: List[Any]) -> List[Any]:
        """移除列表中的重复元素
        
        Args:
            items: 原始列表
            
        Returns:
            List[Any]: 去重后的列表
        """
        # 保留顺序的去重
        seen = set()
        result = []
        
        for item in items:
            if item not in seen:
                seen.add(item)
                result.append(item)
        
        return result
    
    @staticmethod
    def is_list_of_type(items: List[Any], type_: type) -> bool:
        """检查列表中的所有元素是否都是指定类型
        
        Args:
            items: 要检查的列表
            type_: 类型
            
        Returns:
            bool: 是否都是指定类型
        """
        return all(isinstance(item, type_) for item in items)
    
    @staticmethod
    def retry_on_exception(func: Callable, max_retries: int = 3, delay: float = 1.0, exceptions: Tuple[type, ...] = (Exception,)) -> Any:
        """在异常发生时重试函数
        
        Args:
            func: 要执行的函数
            max_retries: 最大重试次数
            delay: 重试间隔（秒）
            exceptions: 捕获的异常类型
            
        Returns:
            Any: 函数返回值
            
        Raises:
            Exception: 如果超过最大重试次数后仍然失败
        """
        retries = 0
        last_exception = None
        
        while retries < max_retries:
            try:
                return func()
            except exceptions as e:
                retries += 1
                last_exception = e
                
                if retries < max_retries:
                    time.sleep(delay)
        
        # 超过最大重试次数后抛出最后一个异常
        raise last_exception
    
    @staticmethod
    def time_function(func: Callable) -> Tuple[Any, float]:
        """测量函数执行时间
        
        Args:
            func: 要测量的函数
            
        Returns:
            Tuple[Any, float]: (函数返回值, 执行时间（秒）)
        """
        start_time = time.time()
        result = func()
        end_time = time.time()
        
        return result, end_time - start_time
    
    @staticmethod
    def create_backup_file(file_path: str, backup_extension: str = ".bak") -> str:
        """创建文件的备份
        
        Args:
            file_path: 原文件路径
            backup_extension: 备份文件扩展名
            
        Returns:
            str: 备份文件路径
            
        Raises:
            FileNotFoundError: 原文件不存在
        """
        if not os.path.exists(file_path):
            raise FileNotFoundError(f"文件不存在: {file_path}")
        
        # 生成备份文件路径
        backup_path = f"{file_path}{backup_extension}"
        
        # 如果备份文件已存在，添加时间戳
        if os.path.exists(backup_path):
            timestamp = int(time.time())
            backup_path = f"{file_path}{backup_extension}.{timestamp}"
        
        # 复制文件内容
        with open(file_path, "rb") as f_src:
            with open(backup_path, "wb") as f_dst:
                f_dst.write(f_src.read())
        
        return backup_path
    
    @staticmethod
    def replace_in_file(file_path: str, old_text: str, new_text: str) -> int:
        """替换文件中的文本
        
        Args:
            file_path: 文件路径
            old_text: 要替换的文本
            new_text: 替换后的文本
            
        Returns:
            int: 替换的次数
            
        Raises:
            FileNotFoundError: 文件不存在
        """
        if not os.path.exists(file_path):
            raise FileNotFoundError(f"文件不存在: {file_path}")
        
        # 读取文件内容
        with open(file_path, "r", encoding="utf-8") as f:
            content = f.read()
        
        # 统计替换次数
        count = content.count(old_text)
        
        # 替换文本
        content = content.replace(old_text, new_text)
        
        # 写回文件
        with open(file_path, "w", encoding="utf-8") as f:
            f.write(content)
        
        return count
    
    @staticmethod
    def extract_pattern_from_file(file_path: str, pattern: str) -> List[str]:
        """从文件中提取匹配正则表达式的文本
        
        Args:
            file_path: 文件路径
            pattern: 正则表达式
            
        Returns:
            List[str]: 匹配的文本列表
            
        Raises:
            FileNotFoundError: 文件不存在
        """
        if not os.path.exists(file_path):
            raise FileNotFoundError(f"文件不存在: {file_path}")
        
        # 读取文件内容
        with open(file_path, "r", encoding="utf-8") as f:
            content = f.read()
        
        # 查找匹配的文本
        return re.findall(pattern, content)
    
    @staticmethod
    def get_platform_info() -> Dict[str, str]:
        """获取操作系统信息
        
        Returns:
            Dict[str, str]: 操作系统信息
        """
        return {
            "system": platform.system(),
            "release": platform.release(),
            "version": platform.version(),
            "machine": platform.machine(),
            "processor": platform.processor(),
            "python_version": platform.python_version(),
            "python_implementation": platform.python_implementation(),
        }
    
    @staticmethod
    def is_windows() -> bool:
        """检查是否是Windows系统
        
        Returns:
            bool: 是否是Windows系统
        """
        return platform.system() == "Windows"
    
    @staticmethod
    def is_macos() -> bool:
        """检查是否是macOS系统
        
        Returns:
            bool: 是否是macOS系统
        """
        return platform.system() == "Darwin"
    
    @staticmethod
    def is_linux() -> bool:
        """检查是否是Linux系统
        
        Returns:
            bool: 是否是Linux系统
        """
        return platform.system() == "Linux"
    
    @staticmethod
    def get_env_variable(name: str, default: Any = None) -> Any:
        """获取环境变量
        
        Args:
            name: 环境变量名称
            default: 默认值
            
        Returns:
            Any: 环境变量值或默认值
        """
        return os.environ.get(name, default)
    
    @staticmethod
    def set_env_variable(name: str, value: str) -> None:
        """设置环境变量
        
        Args:
            name: 环境变量名称
            value: 环境变量值
        """
        os.environ[name] = value
    
    @staticmethod
    def remove_env_variable(name: str) -> None:
        """移除环境变量
        
        Args:
            name: 环境变量名称
        """
        if name in os.environ:
            del os.environ[name]
    
    @staticmethod
    def get_terminal_size() -> Tuple[int, int]:
        """获取终端大小
        
        Returns:
            Tuple[int, int]: (宽度, 高度)
        """
        try:
            # 使用shutil获取终端大小
            import shutil
            columns, lines = shutil.get_terminal_size()
            return columns, lines
        except Exception:
            # 如果无法获取，返回默认值
            return 80, 24
    
    @staticmethod
    def truncate_string(s: str, max_length: int, suffix: str = "...") -> str:
        """截断字符串
        
        Args:
            s: 原始字符串
            max_length: 最大长度
            suffix: 截断后缀
            
        Returns:
            str: 截断后的字符串
        """
        if len(s) <= max_length:
            return s
        
        return s[:max_length - len(suffix)] + suffix
    
    @staticmethod
    def capitalize_words(s: str) -> str:
        """将字符串中每个单词的首字母大写
        
        Args:
            s: 原始字符串
            
        Returns:
            str: 首字母大写后的字符串
        """
        return ' '.join(word.capitalize() for word in s.split())
    
    @staticmethod
    def snake_to_camel(s: str) -> str:
        """将蛇形命名转换为驼峰命名
        
        Args:
            s: 蛇形命名字符串
            
        Returns:
            str: 驼峰命名字符串
        """
        parts = s.split('_')
        return parts[0] + ''.join(part.capitalize() for part in parts[1:])
    
    @staticmethod
    def camel_to_snake(s: str) -> str:
        """将驼峰命名转换为蛇形命名
        
        Args:
            s: 驼峰命名字符串
            
        Returns:
            str: 蛇形命名字符串
        """
        # 插入下划线并转换为小写
        s = re.sub(r'([a-z0-9])([A-Z])', r'\1_\2', s)
        return s.lower()
    
    @staticmethod
    def validate_email(email: str) -> bool:
        """验证电子邮件地址格式
        
        Args:
            email: 电子邮件地址
            
        Returns:
            bool: 格式是否有效
        """
        pattern = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
        return re.match(pattern, email) is not None
    
    @staticmethod
    def validate_url(url: str) -> bool:
        """验证URL格式
        
        Args:
            url: URL字符串
            
        Returns:
            bool: 格式是否有效
        """
        pattern = r"^(https?://)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*/?$"
        return re.match(pattern, url) is not None
    
    @staticmethod
    def generate_random_string(length: int = 16, use_uppercase: bool = True, use_digits: bool = True, use_special_chars: bool = False) -> str:
        """生成随机字符串
        
        Args:
            length: 字符串长度
            use_uppercase: 是否包含大写字母
            use_digits: 是否包含数字
            use_special_chars: 是否包含特殊字符
            
        Returns:
            str: 随机字符串
        """
        import random
        import string
        
        # 定义字符集
        chars = string.ascii_lowercase
        
        if use_uppercase:
            chars += string.ascii_uppercase
        
        if use_digits:
            chars += string.digits
        
        if use_special_chars:
            chars += string.punctuation
        
        # 生成随机字符串
        return ''.join(random.choice(chars) for _ in range(length))
    
    @staticmethod
    def format_number(n: Union[int, float], decimal_places: int = 2) -> str:
        """格式化数字
        
        Args:
            n: 数字
            decimal_places: 小数位数
            
        Returns:
            str: 格式化后的数字字符串
        """
        # 根据数字类型选择格式
        if isinstance(n, int):
            return f"{n:,}"
        else:
            format_str = f"%0.{decimal_places}f"
            return format_str % n
    
    @staticmethod
    def parse_bool(value: Any) -> bool:
        """解析布尔值
        
        Args:
            value: 要解析的值
            
        Returns:
            bool: 解析后的布尔值
        """
        if isinstance(value, bool):
            return value
        
        if isinstance(value, str):
            # 转换为小写进行比较
            value = value.lower()
            
            # 检查常见的真值和假值
            if value in ("true", "yes", "y", "1", "t"):
                return True
            elif value in ("false", "no", "n", "0", "f"):
                return False
        
        # 尝试转换为整数
        try:
            return int(value) != 0
        except (ValueError, TypeError):
            pass
        
        # 尝试转换为浮点数
        try:
            return float(value) != 0.0
        except (ValueError, TypeError):
            pass
        
        # 默认返回布尔值转换结果
        return bool(value)
    
    @staticmethod
    def safe_cast(value: Any, to_type: type, default: Any = None) -> Any:
        """安全地转换类型
        
        Args:
            value: 要转换的值
            to_type: 目标类型
            default: 转换失败时的默认值
            
        Returns:
            Any: 转换后的值或默认值
        """
        try:
            return to_type(value)
        except (ValueError, TypeError, AttributeError):
            return default
    
    @staticmethod
    def get_key_by_value(d: Dict[Any, Any], value: Any) -> Any:
        """根据值获取字典中的键
        
        Args:
            d: 字典
            value: 值
            
        Returns:
            Any: 对应的键，如果值不存在则返回None
        """
        for k, v in d.items():
            if v == value:
                return k
        
        return None
    
    @staticmethod
    def get_nested_value(d: Dict[Any, Any], keys: List[Any], default: Any = None) -> Any:
        """获取嵌套字典中的值
        
        Args:
            d: 嵌套字典
            keys: 键列表
            default: 默认值
            
        Returns:
            Any: 嵌套值或默认值
        """
        current = d
        
        for key in keys:
            if isinstance(current, dict) and key in current:
                current = current[key]
            else:
                return default
        
        return current
    
    @staticmethod
    def set_nested_value(d: Dict[Any, Any], keys: List[Any], value: Any) -> None:
        """设置嵌套字典中的值
        
        Args:
            d: 嵌套字典
            keys: 键列表
            value: 要设置的值
        """
        current = d
        
        for i, key in enumerate(keys):
            if i == len(keys) - 1:
                current[key] = value
            else:
                if key not in current or not isinstance(current[key], dict):
                    current[key] = {}
                current = current[key]
    
    @staticmethod
    def remove_nested_key(d: Dict[Any, Any], keys: List[Any]) -> bool:
        """移除嵌套字典中的键
        
        Args:
            d: 嵌套字典
            keys: 键列表
            
        Returns:
            bool: 是否成功移除
        """
        current = d
        
        for i, key in enumerate(keys):
            if not isinstance(current, dict) or key not in current:
                return False
            
            if i == len(keys) - 1:
                del current[key]
            else:
                current = current[key]
        
        return True